#!/usr/bin/env python
# encoding: utf-8
# @author: Lin Han
# @contact: voldemort22@126.com
# @file: mongo_tools.py
# @time: 2021/3/20 18:57
# @desc:
from typing import Dict, List

import pymongo

from views.configs import *


def total_number_generator(
        collection_name: str,
        database_name: str = MONGO_DATABASE_NAME,
        url: str = MONGO_URL,
):
    """
    总数生成器，用于辅助生成number，确保其唯一。

    :param url:
    :param database_name:
    :param collection_name:
    """
    myclient = pymongo.MongoClient(url)
    mydb = myclient[database_name]
    mycol = mydb[collection_name]
    number_list = []
    for i in mycol.find({}):
        i.pop("_id")

        if "number" in i.keys():
            number_list.append(int(i["number"][6:]))
    if len(number_list) == 0:
        return 1
    else:
        return max(number_list)


def history_clamp_number_generator(collection_name: str = HISTORY_CLAMP_COLLECTION):
    """
    历史夹具的id生成器，会自动根据mongo库里的最大值去加1。
    :param collection_name: 表名
    :return:
    """
    # TODO: 自增数据过快的原因在这里：前面的那个数在千位是1，等于每次多加了1000。现在改回为0了。
    number = str(NUMBER_HISTORY_CLAMP_START + total_number_generator(collection_name=collection_name))
    return number


def history_part_number_generator(collection_name: str = HISTORY_PART_COLLECTION):
    """
    历史零件的id生成器，会自动根据mongo库里的最大值去加1。
    :param collection_name:
    :return:
    """
    number = str(NUMBER_HISTORY_PART_START + total_number_generator(
        database_name=MONGO_DATABASE_NAME,
        collection_name=collection_name,
    ))
    return number


def standard_clamp_number_generator(collection_name: str = STANDARD_CLAMP_COLLECTION):
    """
    id生成器，会自动根据mongo库里的最大值去加1。
    :param collection_name:
    :return:
    """
    number = str(NUMBER_STANDARD_CLAMP_START + total_number_generator(
        database_name=MONGO_DATABASE_NAME,
        collection_name=collection_name,
    ))
    return number


def standard_part_number_generator(collection_name: str = STANDARD_PART_COLLECTION):
    """
    id生成器，会自动根据mongo库里的最大值去加1。
    :param collection_name:
    :return:
    """
    number = str(NUMBER_STANDARD_PART_START + total_number_generator(
        database_name=MONGO_DATABASE_NAME,
        collection_name=collection_name,
    ))
    return number


def parameter_model_number_generator(collection_name: str = PARAMETER_MODEL_COLLECTION):
    """
    id生成器，会自动根据mongo库里的最大值去加1。
    :param collection_name:
    :return:
    """
    number = str(NUMBER_PARAMETER_MODEL_START + total_number_generator(
        database_name=MONGO_DATABASE_NAME,
        collection_name=collection_name,
    ))
    return number


def scene_number_generator(collection_name: str = SCENE_COLLECTION):
    """
    id生成器，会自动根据mongo库里的最大值去加1。
    :param collection_name:
    :return:
    """
    number = str(NUMBER_SCENE_START + total_number_generator(
        database_name=MONGO_DATABASE_NAME,
        collection_name=collection_name,
    ))
    return number


def total_number_generator_only_for_old_clamp(clamp_list: list):
    """
    总数生成器，用于生成number，确保其唯一。

    """
    if len(clamp_list) == 0:
        return 2021010000100001
    else:
        number_list = [int(i["number"]) for i in clamp_list]
        return max(number_list) + 1


def create_one_mongo_value(
        new_value: Dict,
        collection_name: str,
        database_name: str = MONGO_DATABASE_NAME,
        url: str = MONGO_URL,
):
    """
    给数据库里增加一条数据。

    :param new_value:
    :param url:
    :param database_name:
    :param collection_name:
    """
    myclient = pymongo.MongoClient(url)
    mydb = myclient[database_name]
    mycol = mydb[collection_name]
    mycol.insert_one(new_value)


def retrieve_mongo_values(
        filter_conditions: Dict,
        data_type: str,
        collection_name: str,
        database_name: str = MONGO_DATABASE_NAME,
        url: str = MONGO_URL,
) -> List:
    """
    输入查询条件查询数据，返回的是一堆元素为字典数据的列表（理论上），如果列表不止一条数据，那么说明数据库里id不唯一，有问题了。

    :param data_type:
    :param filter_conditions:
    :param url:
    :param database_name:
    :param collection_name:
    """
    myclient = pymongo.MongoClient(url)
    mydb = myclient[database_name]
    mycol = mydb[collection_name]
    result = []
    for i in mycol.find(filter_conditions):
        if i["number"].startswith("20210" + data_type):
            i.pop("_id")
            result.append(i)
    return result


def retrieve_all_mongo_values(
        filter_conditions: Dict,
        collection_name: str,
        database_name: str = MONGO_DATABASE_NAME,
        url: str = MONGO_URL,
) -> List:
    """
    输入查询条件查询数据，返回的是一堆元素为字典数据的列表（理论上）。
    如果根据number查询到的列表不止一条数据，那么说明数据库里id不唯一，有问题了。

    :param filter_conditions:
    :param url:
    :param database_name:
    :param collection_name:
    """
    myclient = pymongo.MongoClient(url)
    mydb = myclient[database_name]
    mycol = mydb[collection_name]
    result = []
    for i in mycol.find(filter_conditions):
        i.pop("_id")
        result.append(i)
    return result


def retrieve_one_mongo_value(
        number: str,
        collection_name: str,
        database_name: str = MONGO_DATABASE_NAME,
        url: str = MONGO_URL,
) -> List:
    """
    输入number，查询数据，返回的是一个只有一条数据的列表（理论上），如果列表不止一条数据，那么说明数据库里id不唯一，有问题了。

    :param number:
    :param url:
    :param database_name:
    :param collection_name:
    """
    myclient = pymongo.MongoClient(url)
    mydb = myclient[database_name]
    mycol = mydb[collection_name]
    result = []
    for i in mycol.find({"number": number}):
        i.pop("_id")
        result.append(i)
    return result


def retrieve_one_mongo_standard_part_value(
        category: str,
        collection_name: str,
        database_name: str = MONGO_DATABASE_NAME,
        url: str = MONGO_URL,
) -> List:
    """
    输入standard part的category，查询数据，返回的是一个只有一条数据的列表（理论上），如果列表不止一条数据，那么说明数据库里id不唯一，有问题了。

    :param category:
    :param url:
    :param database_name:
    :param collection_name:
    """
    myclient = pymongo.MongoClient(url)
    mydb = myclient[database_name]
    mycol = mydb[collection_name]
    result = []
    for i in mycol.find({"category": category}):
        i.pop("_id")
        result.append(i)
    return result


def update_mongo_value(
        filter_condition: Dict[str, str],
        new_value: Dict,
        collection_name: str,
        database_name: str = MONGO_DATABASE_NAME,
        url: str = MONGO_URL,
):
    """
    更新mongodb里的数据，输入一个查询条件，比如该条数据的number字段，以及希望修改的该条数据的new_value字段的值。

    :param filter_condition: 格式如{"number": "2021010000000007"}
    :param new_value: 格式如{"$set": {"isFlag": False}}
    :param url:
    :param database_name:
    :param collection_name:
    """
    myclient = pymongo.MongoClient(url)
    mydb = myclient[database_name]
    mycol = mydb[collection_name]
    mycol.update_one(filter_condition, new_value)


def delete_mongo_value(
        number: str,
        collection_name: str,
        database_name: str = MONGO_DATABASE_NAME,
        url: str = MONGO_URL,
):
    """

    :param number:
    :param url:
    :param database_name:
    :param collection_name:
    """
    myclient = pymongo.MongoClient(url)
    mydb = myclient[database_name]
    mycol = mydb[collection_name]
    result = mycol.delete_many({"number": number})
    return result


def delete_mongo_value_by_filter_condition(
        filter_condition: Dict,
        database_name: str,
        collection_name: str,
        url: str = MONGO_URL,
):
    """

    :param filter_condition:
    :param url:
    :param database_name:
    :param collection_name:
    """
    client = pymongo.MongoClient(url)
    db = client[database_name]
    collection = db[collection_name]
    result = collection.delete_many(filter_condition)
    return result


if __name__ == '__main__':
    print(total_number_generator(collection_name=HISTORY_CLAMP_COLLECTION))
    print(type(total_number_generator(collection_name=HISTORY_CLAMP_COLLECTION)))
